home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Xconq 7.0d37 / source / kernel / mkunits.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-31  |  21.7 KB  |  743 lines  |  [TEXT/KAHL]

  1. /* Unit generation for Xconq.
  2.    Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994 Stanley T. Shebs.
  3.  
  4. Xconq is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.  See the file COPYING.  */
  8.  
  9. #include "conq.h"
  10.  
  11. int at_country_units_max PROTO ((Side *side, int u));
  12.  
  13. int
  14. at_country_units_max(side, u)
  15. Side *side;
  16. int u;
  17. {
  18.     int themax = u_country_units_max(u);
  19.  
  20.     if (themax < 0) return FALSE;
  21.     /* (should adjust for advantage?) */
  22.     return (themax <= side->numunits[u]);
  23. }
  24.  
  25. extern int make_countries PROTO ((void));
  26. extern int make_independent_units PROTO ((void));
  27.  
  28. static void set_people_on_side PROTO ((int x, int y));
  29. static void expand_country PROTO ((int x, int y));
  30. static int country_is_complete PROTO ((Side *side));
  31. static void count_cells PROTO ((int x, int y));
  32. static int good_place PROTO ((int cx, int cy));
  33. static void find_a_place PROTO ((Side *side));
  34. static int valid_unit_place PROTO ((int x, int y));
  35. static int possible_unit_place PROTO ((int x, int y));
  36. static int find_unit_place PROTO ((int u, int cx, int cy, int *xp, int *yp));
  37. static void mung_terrain PROTO ((int x, int y, int u));
  38. static Unit *find_occupant_place PROTO ((Side *side, int u, int x0, int y0));
  39.  
  40. /* Tmp array for counting terrain. */
  41.  
  42. static int *numcells;
  43.  
  44. static int *favorite;
  45.  
  46. static int *totnumcells;
  47.  
  48. /* This is the number of country placements that could not be found to meet
  49.    all the constraints. */
  50.  
  51. static int badcountryplaces = 0;
  52.  
  53. /* This says whether terrain alteration is permissible to make country
  54.    placements work.  This only happens when normal placement starts to fail. */
  55.  
  56. static int mungterrain;
  57.  
  58. static int baseradius;
  59.  
  60. static int tmpradius;
  61.  
  62. static int curmindistance;
  63. static int curmaxdistance;
  64.  
  65. static int sideprogress;
  66. int sidedeltahalf;
  67.  
  68. static int growth;
  69.  
  70. /* Set the people inside the country to be on the country's side.
  71.    Flip a coin along the edges, to make the border more interesting.
  72.    Also don't always overwrite existing people. */
  73.  
  74. static void
  75. set_people_on_side(x, y)
  76. int x, y;
  77. {
  78.     if ((distance(tmpside->startx, tmpside->starty, x, y) <= tmpradius
  79.          || flip_coin())
  80.         && probability(t_country_people(terrain_at(x, y)))
  81.         && (people_side_at(x, y) == NOBODY || flip_coin())) {
  82.     set_people_side_at(x, y, side_number(tmpside));
  83.     }
  84. }
  85.  
  86. /* Expand a country into the given cell. */
  87.  
  88. static void
  89. expand_country(x, y)
  90. int x, y;
  91. {
  92.     int u, t = terrain_at(x, y), ours, theirs, prob;
  93.     Unit *unit;
  94.     
  95.     if (people_side_at(x, y) == NOBODY) {
  96.     prob = t_country_growth(t);
  97.     } else {
  98.     prob = t_country_takeover(t);
  99.     }
  100.     if (probability(prob)) {
  101.     /* Claim the cell, attempt to own it. */
  102.     ours = theirs = FALSE;
  103.     if (unit_at(x, y) == NULL) {
  104.         /* If completely empty, we claim it. */
  105.         ours = TRUE;
  106.         for_all_unit_types(u) {
  107.             tmputype = u;
  108.         if (xrandom(10000) < u_unit_growth(u)
  109.             && !at_country_units_max(tmpside, u)
  110.             && probability(ut_favored(u, t))
  111.             && valid_unit_place(x, y)) {
  112.             unit = create_unit(u, TRUE);
  113.             if (unit != NULL) {
  114.             set_unit_side(unit, tmpside);
  115.             enter_cell(unit, x, y);
  116.                 break;
  117.             }
  118.         }
  119.         if (xrandom(10000) < u_indep_growth(u)
  120.             && !at_country_units_max(tmpside, u)
  121.             && probability(ut_favored(u, t))
  122.             && valid_unit_place(x, y)) {
  123.             unit = create_unit(u, TRUE);
  124.             if (unit != NULL) {
  125.             enter_cell(unit, x, y);
  126.                 break;
  127.             }
  128.         }
  129.         }
  130.     } else {
  131.         /* Somebody is here already. */
  132.         for_all_stack(x, y, unit) {
  133.         if (unit->side != tmpside) {
  134.             if (unit->side != NULL) {
  135.             /* Maybe take over another side's unit. */
  136.             if (xrandom(10000) < u_unit_takeover(unit->type)
  137.                 && !at_country_units_max(tmpside, u)
  138.                 ) {
  139.                 set_unit_side(unit, tmpside);
  140.                 ours = TRUE;
  141.             } else {
  142.                 /* Indicate that we don't have possession of every
  143.                    unit in this cell. */
  144.                 theirs = TRUE;
  145.             }
  146.             } else {
  147.             /* Maybe take over an independent unit. */
  148.             if (xrandom(10000) < u_indep_takeover(unit->type)
  149.                 && !at_country_units_max(tmpside, u)
  150.                 ) {
  151.                 set_unit_side(unit, tmpside);
  152.                 ours = TRUE;
  153.             }
  154.             }
  155.         }
  156.         }
  157.     }
  158.     /* If cell is claimed, and has no opposition, then country gets it. */
  159.     if (ours && !theirs && probability(t_country_people(t))) {
  160.         set_people_side_at(x, y, side_number(tmpside));
  161.     }
  162.     /* Count this cell as one we expanded into. */
  163.     ++growth;
  164.     }
  165.     /* The cell should become known even if not occupied, but we can't
  166.        do that here because view structures don't exist yet. */
  167. }
  168.  
  169. #define announce_unit_progress(n) \
  170.   announce_progress(sideprogress + sidedeltahalf + (sidedeltahalf * (n)) / totnumtodo)
  171.  
  172. /* Place all the units belonging to countries. */
  173.  
  174. int
  175. make_countries()
  176. {
  177.     int x0, y0, u, t, i, tot, x, y;
  178.     int advantage, sideadvantage, favor, x1, y1, dir;
  179.     int canbeinopen[MAXUTYPES];  /* true if type need not be occ at start */
  180.     int numtodo[MAXUTYPES], numindeptodo[MAXUTYPES], totnumtodo, totnumdone;
  181.     int numleft[MAXUTYPES], numindepleft[MAXUTYPES], totleft, numlisted, numfails;
  182.     int checkmins = FALSE;
  183.     int dopeoplesides = FALSE, dopeopleindeps = FALSE;
  184.     int maxradius;
  185.     int numdone = 0;
  186.     Unit *unit, *transport;
  187.     Side *side;
  188.     char tmpbuf2[BUFSIZE];
  189.  
  190.     /* Run this always, unless something important is missing. */
  191.     if (!terrain_defined()) return FALSE;
  192.     /* Calculate whether the minimum required terrain types are present. */
  193.     totnumcells = (int *) xmalloc(numttypes * sizeof(int));
  194.     for_all_terrain_types(t) {
  195.         if (t_country_min(t) > 0) checkmins = TRUE;
  196.     }
  197.     if (checkmins) {
  198.         /* Edge cells are useless for country placement. */
  199.         for_all_interior_cells(x, y) {
  200.             ++totnumcells[terrain_at(x, y)];
  201.         }
  202.         for_all_terrain_types(t) {
  203.             if (t_country_min(t) * numsides > totnumcells[t]) {
  204.                 init_warning("Not enough %s for all %d sides",
  205.                  t_type_name(t), numsides);
  206.                 /* Don't error out, might be extenuating circumstances. */
  207.             }
  208.         }
  209.     }
  210.     announce_lengthy_process("Making countries");
  211.     /* Precompute some important info */
  212.     numcells = (int *) xmalloc(numttypes * sizeof(int));
  213.     favorite = (int *) xmalloc(numutypes * sizeof(int));
  214.     tot = 0;
  215.     for_all_unit_types(u) {
  216.     canbeinopen[u] = FALSE;
  217.     favorite[u] = NONTTYPE;
  218.     favor = 0;
  219.     for_all_terrain_types(t) {
  220.         if (ut_favored(u, t) > 0) canbeinopen[u] = TRUE;
  221.         if (ut_favored(u, t) > favor) {
  222.         favorite[u] = t;
  223.         favor = ut_favored(u, t);
  224.         }
  225.     }
  226.     if (canbeinopen[u]) {
  227.         tot += u_start_with(u) + u_indep_near_start(u);
  228.     }
  229.     }
  230.     /* Make space for people sides if we're going to have any. */
  231.     if (!people_sides_defined()) {
  232.     for_all_terrain_types(t) {
  233.         if (t_country_people(t) > 0) dopeoplesides = TRUE;
  234.         if (t_indep_people(t) > 0) dopeopleindeps = TRUE;
  235.     }
  236.     if (dopeoplesides || dopeopleindeps) {
  237.         allocate_area_people_sides();
  238.     }
  239.     }
  240.     /* If no radius specified, pick something plausible. */
  241.     if (g_min_radius() <= 0) {
  242.     baseradius = max(1, isqrt(3 * tot) / 2);
  243.     } else {
  244.     baseradius = g_min_radius();
  245.     }
  246.     curmindistance = g_min_separation();
  247.     curmaxdistance = g_max_separation();
  248.     badcountryplaces = 0;
  249.     for_all_sides(side) {
  250.     sideprogress = (100 * numdone++) / numsides;
  251.     sidedeltahalf = (100 / numsides) / 2;
  252.     announce_progress(sideprogress);
  253.     if (!country_is_complete(side)) {
  254.         sideadvantage = max(1, side->advantage);
  255.         advantage = (side->player ? side->player->advantage : sideadvantage);
  256.         if (advantage > 1) {
  257.         tmpradius = (baseradius * isqrt(advantage * 100) + 9) / 10;
  258.         } else {
  259.             tmpradius = baseradius;
  260.         }
  261.         /* Discover or generate the country's center. */
  262.         mungterrain = FALSE;
  263.         find_a_place(side);
  264.         x0 = side->startx;  y0 = side->starty;
  265.         Dprintf("%s starts around %d,%d\n", side_desig(side), x0, y0);
  266.         announce_progress(sideprogress + sidedeltahalf);
  267.         totnumtodo = totnumdone = 0;
  268.         for_all_unit_types(u) {
  269.         numtodo[u] = numindeptodo[u] = 0;
  270.         if (type_allowed_on_side(u, side)) {
  271.             numtodo[u] = (u_start_with(u) * advantage) / sideadvantage;
  272.             totnumtodo += numtodo[u];
  273.         }
  274.         if (type_allowed_on_side(u, NULL)) {
  275.             numindeptodo[u] = (u_indep_near_start(u) * advantage) / sideadvantage;
  276.             totnumtodo += numindeptodo[u];
  277.         }
  278.         numleft[u] = numindepleft[u] = 0;
  279.         }
  280.         /* First do units actually belonging to the side initially. */
  281.         for_all_unit_types(u) {
  282.         if (canbeinopen[u]) {
  283.             for (i = 0; i < numtodo[u]; ++i) {
  284.             if (find_unit_place(u, x0, y0, &x, &y)) {
  285.                 if ((unit = create_unit(u, TRUE)) != NULL) {
  286.                 set_unit_side(unit, side);
  287.                 enter_cell(unit, x, y);
  288.                    announce_unit_progress(++totnumdone);
  289.                 }
  290.             } else {
  291.                 /* If can't find places for this type, give up. */
  292.                     numleft[u] = numtodo[u] - i;
  293.                 break;
  294.             }
  295.             }
  296.         }
  297.         }
  298.         /* Now do independents in the initial country area. */
  299.         for_all_unit_types(u) {
  300.         for (i = 0; i < numindeptodo[u]; ++i) {
  301.             if (find_unit_place(u, x0, y0, &x, &y)) {
  302.             if ((unit = create_unit(u, TRUE)) != NULL) {
  303.                 enter_cell(unit, x, y);
  304.                 announce_unit_progress(++totnumdone);
  305.             }
  306.             } else {
  307.             /* If can't find places for this type, give up. */
  308.             numindepleft[u] = numindeptodo[u] - i;
  309.             break;
  310.             }
  311.         }
  312.         }
  313.         /* Now do units that have to be occupants.  Note that if occupants
  314.            are allowed in independent units, then they might be
  315.            placed in one. */
  316.         for_all_unit_types(u) {
  317.         if (!canbeinopen[u]) {
  318.             for (i = 0; i < numtodo[u]; ++i) {
  319.             if ((transport = find_occupant_place(side, u, x0, y0))
  320.                 != NULL) {
  321.                 if ((unit = create_unit(u, TRUE)) != NULL) {
  322.                 set_unit_side(unit, side);
  323.                 enter_transport(unit, transport);
  324.                    announce_unit_progress(++totnumdone);
  325.                 }
  326.             } else {
  327.                    numleft[u] = numtodo[u] - i;
  328.                 break;
  329.             }
  330.             }
  331.         }
  332.         }
  333.         /* Now warn about what couldn't be placed. */
  334.         totleft = numlisted = numfails = 0;
  335.         tmpbuf2[0] = '\0';
  336.         for_all_unit_types(u) {
  337.         totleft += numleft[u];
  338.         if (numleft[u] > 0 && numlisted < 5) {
  339.             ++numfails;
  340.             strcat(tmpbuf2, " ");
  341.             strcat(tmpbuf2, u_type_name(u));
  342.         }
  343.         }
  344.         if (totleft > 0) {
  345.         char tmpbuf3[BUFSIZE];
  346.  
  347.         init_warning("could not put %d units in %s country (%s%s)",
  348.                  totleft, shortest_side_title(side, tmpbuf3),
  349.                  tmpbuf2, (numfails >= 5 ? " etc" : ""));
  350.         }
  351.     }
  352.     /* Now set the side of the people in this country. */
  353.     tmpside = side;
  354.     apply_to_area(side->startx, side->starty, tmpradius + 1,
  355.               set_people_on_side);
  356.     /* Make sure each unit has people there, if allowed at all. */
  357.     for_all_side_units(side, unit) {
  358.         if (inside_area(unit->x, unit->y)
  359.             && t_country_people(terrain_at(unit->x, unit->y)) > 0) {
  360.         set_people_side_at(unit->x, unit->y, side_number(side));
  361.         }
  362.     }
  363.     }
  364.     finish_lengthy_process();
  365.     /* Grow each country out to a maximum radius. */
  366.     announce_lengthy_process("Growing countries");
  367.     maxradius = min(area.width, g_radius_max());
  368.     for_all_sides(side)
  369.       side->finalradius = maxradius;
  370.     for (i = baseradius; i < maxradius; ++i) {
  371.         announce_progress((100 * (i - baseradius)) / (maxradius - baseradius));
  372.     for_all_sides(side) {
  373.         /* If side still allowed to grow, expand it. */
  374.         if (side->finalradius == maxradius) {
  375.             tmpside = side;
  376.             growth = 0;
  377.             apply_to_ring(side->startx, side->starty, i - 2, i,
  378.                   expand_country);
  379.         /* If no actual growth happened in a step, the country
  380.            might have reached its natural size. */
  381.             if (growth == 0 && probability(g_growth_stop())) {
  382.             side->finalradius = i;
  383.             }
  384.         }
  385.     }
  386.     }
  387.     /* Do a couple "consolidation" steps to fill in "jaggies". */
  388.     for (i = 0; i < 2; ++i) {
  389.     for_all_sides(side) {
  390.         tmpside = side;
  391.         apply_to_ring(side->startx, side->starty,
  392.               baseradius, side->finalradius - 1,
  393.               expand_country);
  394.     }
  395.     }
  396.     /* Also remove isolated populations surrounded by one other side. */
  397.     if (people_sides_defined()) {
  398.     for_all_interior_cells(x, y) {
  399.         int pop, pop2, majoritypop;
  400.         
  401.         if ((pop = people_side_at(x, y)) != NOBODY) {
  402.         majoritypop = NOBODY;
  403.         for_all_directions(dir) {
  404.             if (interior_point_in_dir(x, y, dir, &x1, &y1)) {
  405.             if ((pop2 = people_side_at(x1, y1)) == pop)
  406.               goto nextcell;
  407.             if (majoritypop == NOBODY) {
  408.                 majoritypop = pop2;
  409.             } else {
  410.                 if (pop2 != majoritypop) goto nextcell;
  411.             }
  412.             }
  413.         }
  414.         if (majoritypop != NOBODY) {
  415.             set_people_side_at(x, y, majoritypop);
  416.         }
  417.         }
  418.       nextcell:
  419.         pop = pop;
  420.     }
  421.     }
  422.     finish_lengthy_process();
  423.     /* Warn about any difficulties encountered. */
  424.     if (badcountryplaces > 0) {
  425.         init_warning("%d of %d sides have undesirable locations",
  426.              badcountryplaces, numsides);
  427.     }
  428.     return TRUE;
  429. }
  430.  
  431. /* Test to see whether the side's pre-existing setup already suffices
  432.    as a country in this game. */
  433.  
  434. static int
  435. country_is_complete(side)
  436. Side *side;
  437. {
  438.     int u, numunits[MAXUTYPES];
  439.     Unit *unit;
  440.     int sideadvantage = max(1, side->advantage);
  441.     int advantage = (side->player ? side->player->advantage : sideadvantage);
  442.  
  443.     for_all_unit_types(u) numunits[u] = 0;
  444.     /* Count up all and only the completed and present units. */
  445.     for_all_side_units(side, unit) {
  446.         if (in_play(unit)) {
  447.         ++numunits[unit->type];
  448.     }
  449.     }
  450.     for_all_unit_types(u) {
  451.     if (numunits[u] < ((u_start_with(u) * advantage) / sideadvantage)) return FALSE;
  452.     }
  453.     return TRUE;
  454. }
  455.  
  456. /* Count the cell as being of a particular type. */
  457.  
  458. static void
  459. count_cells(x, y)
  460. int x, y;
  461. {
  462.     ++numcells[terrain_at(x, y)];
  463. }
  464.  
  465. /* Test whether a given location is desirable for a country.  It should be
  466.    in the right distance range from other countries, and have enough of
  467.    the right sorts of terrain. */
  468.  
  469. static int
  470. good_place(cx, cy)
  471. int cx, cy;
  472. {
  473.     int toofar = TRUE, notfirst = FALSE, px, py, t;
  474.     Side *side;
  475.  
  476.     /* Check the candidate position against the other countries' positions. */
  477.     for_all_sides(side) {
  478.     px = side->startx;  py = side->starty;
  479.     if (inside_area(px, py)) {
  480.         notfirst = TRUE;
  481.         /* Min separation default allows any min separation. */
  482.         if (distance(cx, cy, px, py) < curmindistance) return FALSE;
  483.         /* Default max separation says pos can never be too far away. */
  484.         if (curmaxdistance < 0
  485.             || distance(cx, cy, px, py) < curmaxdistance) toofar = FALSE;
  486.     }
  487.     }
  488.     if (toofar && notfirst) return FALSE;
  489.     /* Count the types of terrain in the country. */
  490.     for_all_terrain_types(t) numcells[t] = 0;
  491.     apply_to_area(cx, cy, tmpradius, count_cells);
  492.     /* Check against our upper and lower limits on terrain. */
  493.     for_all_terrain_types(t) {
  494.         if (numcells[t] < t_country_min(t)) return FALSE;
  495.     if (t_country_max(t) >= 0
  496.         && numcells[t] > t_country_max(t)) return FALSE;
  497.     }
  498.     return TRUE;
  499. }
  500.  
  501. /* Work hard to find a place for a side's country.  First make some random
  502.    trials, then start searching from the center of the area outwards.
  503.    Then just pick a place and plan to patch up the terrain later. */
  504.  
  505. static void
  506. find_a_place(side)
  507. Side *side;
  508. {
  509.     int tries, x, y, maxtries = area_cells() / 5;
  510.     Unit *unit;
  511.  
  512.     Dprintf("%s country ", side_desig(side));
  513.     /* First see if any of our units is already at a good location
  514.        to put the whole country. */
  515.     /* (should choose randomly from units first?) */
  516.     for_all_side_units(side, unit) {
  517.     if (in_play(unit) && good_place(unit->x, unit->y)) {
  518.         side->startx = unit->x;  side->starty = unit->y;
  519.         Dprintf("placed at unit %s\n", unit_desig(unit));
  520.         return;
  521.     }
  522.     }
  523.     /* Then try any of the independent units.  Probability of choosing
  524.        one is inversely proportional to the total number of units. */
  525.     for_all_side_units(indepside, unit) {
  526.     if (in_play(unit)
  527.         && good_place(unit->x, unit->y)
  528.         && probability(max(1, 100 / numunits))) {
  529.         side->startx = unit->x;  side->starty = unit->y;
  530.         Dprintf("placed at indep unit %s\n", unit_desig(unit));
  531.         return;
  532.     }
  533.     }
  534.     /* Then try some random locations. */
  535.     for (tries = 0; tries < maxtries; ++tries) {
  536.     if (tries % 10 == 0) {
  537.         announce_progress(sideprogress +
  538.                   ((sidedeltahalf / 2) * tries) / maxtries);
  539.     }
  540.     random_point(&x, &y);
  541.     /* Filter out points that are right on the edge.  If that's
  542.        where the only valid starting places are, the exhaustive
  543.        search will still find them. */
  544.     if (between(2, y, area.height - 2)
  545.         && between(2, x, area.width - 2)
  546.         && good_place(x, y)) { 
  547.         side->startx = x;  side->starty = y;
  548.         Dprintf("placed on try %d\n", tries);
  549.         return;
  550.     }
  551.     }
  552.     /* Then search exhaustively, starting from the center of the area. */
  553.     if (search_around(area.width / 2, area.height / 2,
  554.               area.width / 2 + area.height / 2,
  555.               good_place, &x, &y, 1)) {
  556.     side->startx = x;  side->starty = y;
  557.     Dprintf("placed after search\n");
  558.     return;
  559.     }
  560.     /* This should be a place in the area no matter what. */
  561.     random_point(&x, &y);
  562.     side->startx = x;  side->starty = y;
  563.     Dprintf("placed randomly\n");
  564.     ++badcountryplaces;
  565.     /* Since placement has become difficult, we get permission to alter
  566.        the terrain if necessary, while placing units. */
  567.     mungterrain = TRUE;
  568. }    
  569.  
  570. /* The basic conditions that *must* be met by an initial unit placement. */
  571.  
  572. static int
  573. valid_unit_place(x, y)
  574. int x, y;
  575. {
  576.     int t = terrain_at(x, y);
  577.  
  578.     return (inside_area(x, y)
  579.         && ut_favored(tmputype, t) > 0
  580.         && !ut_vanishes_on(tmputype, t)
  581.         && !ut_wrecks_on(tmputype, t)
  582.         && type_can_occupy_cell(tmputype, x, y));
  583. }
  584.  
  585. static int
  586. possible_unit_place(x, y)
  587. int x, y;
  588. {
  589.     return (inside_area(x, y) && unit_at(x, y) == NULL);
  590. }
  591.  
  592. /* Find a place somewhere in the designated area, following constraints
  593.    on terrain and adjacency.  Returns success of placement. */
  594.  
  595. static int
  596. find_unit_place(u, cx, cy, xp, yp)
  597. int u, cx, cy, *xp, *yp;
  598. {
  599.     int tries, x, y;
  600.     int maxtries = tmpradius * tmpradius * 5;
  601.  
  602.     Dprintf("%s place found ", u_type_name(u));
  603.     tmputype = u;
  604.     for (tries = 0; tries < maxtries; ++tries) {
  605.     if (random_point_near(cx, cy, tmpradius, &x, &y)) {
  606.         if (mungterrain
  607.             && !valid_unit_place(x, y)
  608.             && possible_unit_place(x, y)
  609.         && favorite[u] != NONTTYPE
  610.         && probability(ut_favored(u, favorite[u]))) {
  611.         Dprintf("(by munging) ");
  612.         mung_terrain(x, y, u);
  613.         }
  614.         if (valid_unit_place(x, y)
  615.             && probability(ut_favored(u, terrain_at(x, y)))) {
  616.             *xp = x;  *yp = y;
  617.         Dprintf("on try %d of %d\n", tries, maxtries);
  618.         return TRUE;
  619.         }
  620.     }
  621.     }
  622.     /* Random points aren't working, switch to exhaustive search. */
  623.     if (search_around(cx, cy, tmpradius, valid_unit_place, &x, &y, 1)) {
  624.     *xp = x;  *yp = y;
  625.     Dprintf("after search\n");
  626.     return TRUE;
  627.     }
  628.     /* Search again, just find a location that we can alter to suit. */
  629.     if (favorite[u] != NONTTYPE) {
  630.         if (search_around(cx, cy, tmpradius, possible_unit_place, &x, &y, 1)) {
  631.             mung_terrain(x, y, u);
  632.         *xp = x;  *yp = y;
  633.         Dprintf("(by munging) after search\n");
  634.         return TRUE;
  635.     }
  636.     }
  637.     Dprintf("- NOT!\n");
  638.     return FALSE;
  639. }
  640.  
  641. static void
  642. mung_terrain(x, y, u)
  643. int x, y, u;
  644. {
  645.     int dir, x1, y1;
  646.  
  647.     /* Alter the terrain to be compatible with the given unit type. */
  648.     set_terrain_at(x, y, favorite[u]);
  649.     /* Mung some empty adjacent cells also, improves appearance. */
  650.     for_all_directions(dir) {
  651.     if (interior_point_in_dir(x, y, dir, &x1, &y1)) {
  652.         if (unit_at(x1, y1) == NULL && flip_coin()) {
  653.         set_terrain_at(x1, y1, favorite[u]);
  654.         }
  655.     }
  656.     }
  657. }
  658.  
  659. static Unit *
  660. find_occupant_place(side, u, x0, y0)
  661. Side *side;
  662. int u, x0, y0;
  663. {
  664.     Unit *transport;
  665.  
  666.     /* (should cast about randomly first, then do full search) */
  667.     for_all_side_units(side, transport) {
  668.     if (is_unit(transport)
  669.         && inside_area(transport->x, transport->y)
  670.         && type_can_occupy(u, transport)) {
  671.         return transport;
  672.     }
  673.     }
  674.     /* (should be able to look at indep units in country) */
  675.     return NULL;
  676. }
  677.  
  678. /* A method that scatters independent units over the world. */
  679.  
  680. int
  681. make_independent_units()
  682. {
  683.     int u, t, x, y;
  684.     int doindeptype[MAXUTYPES], doanytype = FALSE, doindeppeople = FALSE;
  685.     Unit *unit;
  686.  
  687.     /* Can't do anything without some terrain. */
  688.     if (!terrain_defined())
  689.       return FALSE;
  690.     /* Decide which types will be put down. */
  691.     for_all_unit_types(u) {
  692.         doindeptype[u] = FALSE;
  693.         for_all_terrain_types(t) {
  694.             if (ut_indep_density(u, t) > 0 && !ut_vanishes_on(u, t)) {
  695.                 doindeptype[u] = TRUE;
  696.                 doanytype = TRUE;
  697.                 break;
  698.             }
  699.         }
  700.     }
  701.     /* Make space for people sides if we're going to have any. */
  702.     if (!people_sides_defined()) {
  703.     for_all_terrain_types(t) {
  704.         if (t_indep_people(t) > 0) doindeppeople = TRUE;
  705.     }
  706.     if (doindeppeople) {
  707.         allocate_area_people_sides();
  708.     }
  709.     }
  710.     /* If no units or peoples to do, don't waste time going through
  711.        the world. */
  712.     if (!doanytype && !doindeppeople)
  713.       return FALSE;
  714.     announce_lengthy_process("Making independents");
  715.     /* Now apply the process to each cell individually. */
  716.     for_all_interior_cells(x, y) {
  717.         /* Progress is approx proportional to "column" being worked on. */
  718.         if (y == 1 && x % 5 == 0) announce_progress((x * 100) / area.width);
  719.     t = terrain_at(x, y);
  720.     for_all_unit_types(u) {
  721.         if (doindeptype[u]) {
  722.         if (ut_indep_density(u, t) > xrandom(10000)) {
  723.                 if (!ut_vanishes_on(u, t)
  724.             && type_can_occupy_cell(u, x, y)) {
  725.             if ((unit = create_unit(u, TRUE)) != NULL) {
  726.                 enter_cell(unit, x, y);
  727.                 }
  728.             }
  729.         }
  730.         }
  731.     }
  732.     if (doindeppeople
  733.         /* Don't put indeps on top of people already on a side. */
  734.         && people_side_at(x, y) == NOBODY
  735.         && probability(t_indep_people(t))) {
  736.         /* 0 represents indep people present */
  737.         set_people_side_at(x, y, 0);
  738.     }
  739.     }
  740.     finish_lengthy_process();
  741.     return TRUE;
  742. }
  743.